package play;

import java.util.ArrayList;

import mech.AttackQ;
import mech.UsefulMethods;
import obj.Enemy;
import obj.Platform;
import obj.Projectile;

import org.newdawn.slick.Color;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

import util.Settings;
import util.WorldLoader;

/**
 * The battle-stage in which the player fights the enemies.
 * This is a warped location from the world supposedly.
 * @author VincentLy
 */
public class BattleStage extends BasicGameState{ 
	
	public BattleStage(){super();}

	/**
	 * Initializes platforms and the player location.
	 * @author VincentLy
	 */
	public void init(GameContainer gc,StateBasedGame sbg) throws SlickException { 
		Things.loader = new WorldLoader("res/battleplatforms.txt");
		Things.platforms = Things.loader.getPlatforms();
		if(Things.player!=null)
			Things.player.move(100,300);
	}

	/**
	 * Updates the objects in the battlestage as well as the scene change and input.
	 * @author VincentLy
	 */
	public void update(GameContainer gc,StateBasedGame sbg, int delta) throws SlickException {
		//handle inputs
		handleInput(gc,sbg);  
		//update enemies
		for(Enemy e:Things.newenemies)
			Things.enemies.add(e);
		Things.newenemies.clear();
		for(Enemy e:Things.enemies){
			e.update();
			UsefulMethods.platformCollisions(e);
		}	
		//update projectiles
		for(Projectile p:Things.newprojectiles)
			Things.projectiles.add(p);
		Things.newprojectiles.clear();
		for(Projectile p:Things.projectiles)
			p.update();
		//update player
		Things.player.update();     
		//check platform collisions
		UsefulMethods.platformCollisions(Things.player);	
		//check enemy collisions
		UsefulMethods.enemyCollisions(Things.player,sbg);
		//check projectile collisions
		UsefulMethods.bulletCollisions(gc,sbg);
		//check for screen scrolling
		float[] chg = UsefulMethods.sceneChange(Things.scene,Things.player);
		Settings.tx+=chg[0];
		Settings.ty+=chg[1];	
	}

	/**
	 * Specifically handles the player input.
	 * @param gc - GameContainer
	 * @param sbg - StateBasedGame
	 * @throws SlickException
	 * @author VincentLy
	 */
	public void handleInput(GameContainer gc,StateBasedGame sbg) throws SlickException{
		Input input = gc.getInput();
		if(!Things.player.isHit()){ 
			//jumping
			if(input.isKeyPressed(Input.KEY_W)){  
				AttackQ.add("w");
				if(Things.player.jumps()>0){
					Things.player.setPlatform(null);
					if(Things.player.jumps()==2)
						Things.player.setYVel(60);    
					else if(Things.player.jumps()==1)
						Things.player.setYVel(50);
					Things.player.setJumps(Things.player.jumps()-1);
					Things.player.jump();
				}				
			}	    	
			if(!Things.player.isUsingMove() && !Things.player.isDucking()){
				//moving left
				if(input.isKeyDown(Input.KEY_A)){
					Things.player.setXVel(-30);    		
					Things.player.setDir(-1); 
					Things.player.walkBwd();
				}    	
				//moving right
				else if(input.isKeyDown(Input.KEY_D)){
					Things.player.setXVel(30);    	
					Things.player.setDir(1);
					Things.player.walkFwd();
				}   
				else
					Things.player.stop();
			}
		}
		//crouching
		if(input.isKeyDown(Input.KEY_S)){
			if(Things.player.platform()!=null)
				Things.player.duck();
			Things.player.setYVel(Things.player.yvel()-1);
		}
		else
			Things.player.rise();
		//music
		if(input.isKeyPressed(Input.KEY_M))
			gc.setMusicOn(!gc.isMusicOn());  
		//pausing
		if(input.isKeyPressed(Input.KEY_P))
			sbg.enterState(Settings.pmID);	
		//input keys
		if(input.isKeyPressed(Input.KEY_S))
			AttackQ.add("s");
		if(input.isKeyPressed(Input.KEY_A))
			AttackQ.add("a");
		if(input.isKeyPressed(Input.KEY_D))
			AttackQ.add("d");
		if(!Things.player.isDucking()){
			if(input.isKeyPressed(Input.KEY_K) && Things.player.canUseBulletHeaven())
				AttackQ.add("k");		
			if(input.isKeyPressed(Input.KEY_J))
				AttackQ.add("j");		
		}
	}

	/**
	 * Draws the objects in the battlestage as well as screen text and animations.
	 * @author VincentLy
	 */
	public void render(GameContainer gc,StateBasedGame sbg, Graphics g) throws SlickException{     	
		g.setAntiAlias(true);  
		g.setBackground(Settings.bg);  
		g.translate(Settings.tx,Settings.ty);  
		for(Platform p:Things.platforms)
			g.texture(p,Settings.texture,true);		
		for(Enemy e:Things.enemies)
			e.draw(g);		
		ArrayList<Projectile> copy = new ArrayList<Projectile>(Things.projectiles);
		for(Projectile p:copy)
			p.draw(g);
		Things.player.draw(g);
		g.setColor(Color.white);
		UsefulMethods.map(g);
		if(Things.enemies.isEmpty()){			
			Things.projectiles.clear();
			Things.newprojectiles.clear();
			Things.player.stop();
			Things.player.setYVel(0);
			int gold = (int)(Math.random()*50+50);
			Things.gold+=gold;
			Settings.dialog = new String[]{"Battle Won!","Congratulations on beating the enemies!","You got some gold!","Return to the world."};
			sbg.enterState(Settings.diID);	
		}	
		g.setColor(Color.white);
		if(System.currentTimeMillis()-Settings.time<2500)
			g.drawString("Battle Stage",-Settings.tx+Settings.screenX/2-g.getFont().getWidth("Battle Stage")/2,-Settings.ty+100);
	}

	/**
	 * @return id
	 * @author VincentLy
	 */
	public int getID() {return Settings.sID;}    
}